Skip to content

fix(workspace): [workspace.build] 要作用到「作为兄弟成员依赖被编译」的成员 - #539

Merged
Sunrisepeak merged 2 commits into
mainfrom
feat/workspace-build-reaches-sibling-members
Aug 30, 2026
Merged

fix(workspace): [workspace.build] 要作用到「作为兄弟成员依赖被编译」的成员#539
Sunrisepeak merged 2 commits into
mainfrom
feat/workspace-build-reaches-sibling-members

Conversation

@Sunrisepeak

Copy link
Copy Markdown
Member

#538 的后续。不是由失败发现的,是自审时问了这个特性必然引出的完备性问题:
[workspace.build] 会不会作用到「作为另一个成员的 path 依赖被编译」的那个成员?

实测:不会。

mcpp build -p appb        appb  -DWS_FLAG=1 -std=c++26
                          liba              -std=c++26      ← 兄弟成员

继承只发生在「命令自己那份 manifest 被加载」的地方,于是成员之间互相依赖的
workspace —— 也就是最普通的形态 —— 在同一条命令里,一个包拿到了标志,另一个没有。

[workspace.package] standard 把这个洞盖住了:标准出于 BMI 兼容性本来就从根包
全图施加,所以它照样到了兄弟成员那里。只有当 [build] 的键也变得可继承之后,
这个缺口才第一次可达。

两半,各自放在它的消费者读它的那个点

  • [workspace.package] 放在依赖的加载点 —— 成员可以合法省略 package.version
    (由 workspace 提供),否则 parser 会为一个 workspace 确实提供了的字段拒绝它,
    而且报的是成员的 manifest,不是那张回答了问题的表。
  • [workspace.build] 放在 makePackageRoot —— 两个依赖装配点共用的唯一漏斗,
    也正是 include 目录从 manifest 里被取走的时刻。更晚的改动会作用到 flags 而
    静默地作用不到 include dirs。

否定用例在同一个 fixture 里

is_workspace_member 问的是 workspace 自己的 members 列表,而不是「这个路径在不在
workspace 目录下」:树里的 vendored 副本、example,不是成员,而成员的标志正是它们
不能获得的东西。

一个「对所有 path 依赖都继承」的修法能单独通过肯定用例 —— 所以 321 在同一个
fixture 里同时断言两个方向。

inherit_workspace_config 现在是这两半的组合,三个调用点不会再漂移。

…pendency

Found by asking the completeness question the feature invites and not by a
failure: does `[workspace.build]` reach a member that is compiled as ANOTHER
member's `path` dependency? Measured, it did not.

    mcpp build -p appb        appb  -DWS_FLAG=1 -std=c++26
                              liba              -std=c++26      <- the sibling

Inheritance ran only where the command's own manifest is loaded, so a workspace
where members depend on each other — the ordinary shape, not an exotic one —
got the flags on one package and not on the others, in the same command.

`[workspace.package] standard` hid it. The standard is imposed graph-wide from
the root for BMI-compatibility reasons, so it reached the sibling anyway; the
gap only became reachable once a `[build]` key was inheritable too.

Two halves, applied where each one's consumer reads it:

  - `[workspace.package]` at the dependency LOAD site, because a member may
    legally omit `package.version` when the workspace supplies it, and the
    parser would otherwise refuse it for a field the workspace does provide —
    naming the member's manifest rather than the table that answers.
  - `[workspace.build]` in `makePackageRoot`, the one funnel both
    dependency-assembly sites go through, and the point at which the include
    directories are captured from the manifest. A later mutation would reach
    the flags and silently not the include dirs.

`is_workspace_member` asks the workspace's own `members` list rather than "is
this path inside the tree": a vendored copy or an example living under the
workspace is not a member, and a member's flags are exactly what it must not
acquire. 321 asserts both directions in one fixture, because a fix that
inherited to every `path` dependency would pass the positive alone.

`inherit_workspace_config` is now the composition of the two halves, so the
three call sites cannot drift.
CHANGELOG gains the two facts a user needs and could not infer: inheritance
reaches a member compiled as a sibling's `path` dependency (and does NOT reach
a non-member path dependency), and a relative `include_dirs` is anchored to the
workspace root.

The design document's review record gains the round that found them. All three
share one shape — a rule implemented at the one place its FIRST consumer reads
it, for a key that has three — which is §2's defect one layer up.
@Sunrisepeak
Sunrisepeak merged commit 43253be into main Aug 30, 2026
36 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants